﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XingLucifer.IBase;

namespace XingLucifer.Devices.Devices.ElectronicScales
{
    public class JS_03B : IDevices
    {
        private ICommunication _com;
        private byte[] _cmd;
        private List<byte> _cacheByte = new List<byte>(1024);
        private CancellationTokenSource _tokenSource;
        public JS_03B(ICommunication com, CancellationTokenSource tokenSource)
        {
            _com = com;
            _cmd = Encoding.ASCII.GetBytes("DZ\r\n");
            _tokenSource = tokenSource;
        }

        public bool WriteSingle(object value, int address, int offset, int length, int count = 3)
        {
            try
            {
                _com.Write(_cmd);
                return true;
            }
            catch (Exception)
            {
            }
            return false;
        }

        public TValue ReadSingle<TValue>(int address = 0, int length = 0, int count = 3)
        {
            byte[] bytes = _cacheByte.ToArray();
            _cacheByte.Clear();
            double? value = GetWeight(bytes);
            return value == null ? default : (TValue)(object)value;
        }

        /// <summary>
        /// TC60型号电子秤解析
        /// </summary>
        /// <param name="originalbyte">称重数据</param>
        /// <returns>值不正确为0</returns>
        private double? GetWeight(byte[] originalbyte)
        {
            try
            {
                if (originalbyte.Length >= 20)
                {
                    byte[] bytes = new byte[0];
                    var str = Encoding.ASCII.GetString(originalbyte).Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    if (str.Length > 1)
                    {
                        int count = 0;
                        for (int i = str.Length - 1; i > 0; i--)
                        {
                            if (str[i].Length == 18
                                && str[i].Contains("ST,NT,"))
                            {
                                count = i;
                                break;
                            }
                        }
                        bytes = Encoding.ASCII.GetBytes(str[count]);
                    }
                    else
                    {
                        bytes = Encoding.ASCII.GetBytes(str[0]);
                        if (bytes.Length < 18) return null;
                    }
                    if (bytes.Length != 18) return null;
                    var section1 = Encoding.ASCII.GetString(bytes, 0, 2);//ST
                    var section2 = Encoding.ASCII.GetString(bytes, 3, 2);//NT
                    var section3 = Encoding.ASCII.GetString(bytes, 6, 1);//+
                    var section4 = Encoding.ASCII.GetString(bytes, 7, 7);//value
                    double.TryParse(section4, out double w);
                    if (section1.ToUpper() == "ST" && section2.ToUpper() == "NT") return w;
                }
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }

        public Task Read()
        {
            return Task.Run(() =>
            {
                while (!_tokenSource.Token.IsCancellationRequested)
                {
                    _cacheByte.AddRange(_com.Read(20));
                    if (_cacheByte.Count > 1023)
                    {
                        _cacheByte.Clear();
                    }
                    Thread.Sleep(50);
                }
            });
        }

        public bool WriteClass<TClass>(TClass value, int address, int count = 3) where TClass : class
        {
            throw new NotImplementedException("未实现");
        }

        public TClass ReadClass<TClass>(int address, TClass obj = null, int count = 3) where TClass : class
        {
            throw new NotImplementedException("未实现");
        }

        public bool Open() => _com.Open();

        public string Close() => _com.Close();
    }
}
